﻿using Core.Authorization;
using Core.Identity.UserProfiles.Features.Commands.Delete;
using Core.Identity.UserProfiles.Features.Commands.Edit;
using Core.Identity.UserProfiles.Features.Queries.GetById;
using Core.Identity.Users.Dtos;
using Core.Identity.Users.Features.Commands.AssignRole;
using Core.Identity.Users.Features.Commands.BatchDelete;
using Core.Identity.Users.Features.Commands.Create;
using Core.Identity.Users.Features.Commands.Enable;
using Core.Identity.Users.Features.Commands.Register;
using Core.Identity.Users.Features.Commands.ResetPassword;
using Core.Identity.Users.Features.Commands.Update;
using Core.Identity.Users.Features.Commands.UpdateMine;
using Core.Identity.Users.Features.Commands.UploadAvatar;
using Core.Identity.Users.Features.Queries.GetById;
using Core.Identity.Users.Features.Queries.GetRoleById;
using Core.Identity.Users.Features.Queries.PaginationQuery;
using Core.Interfaces.Users;
using Core.Models;
using Infrastructure.Auth.Policy;
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;

namespace Infrastructure.Identity.Users.Endpoints;

public static class UserEndpoints
{
    public static IEndpointRouteBuilder MapUserEndpoints(this IEndpointRouteBuilder app)
    {
        var group = app.MapGroup("/api/user")
                       .WithTags("User")
                       .WithDescription("用户管理");

        // -----------------------
        // 注册用户（匿名）
        // POST /api/user/register
        // -----------------------
        group.MapPost("/register", async (
            [FromHeader(Name = TenantConstants.Identifier)] string tenant,
            [FromBody] RegisterCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .AllowAnonymous()
        .WithDescription("注册用户")
        .WithMetadata(new EndpointNameMetadata(nameof(RegisterCommand))); ;

        // -----------------------
        // 创建用户
        //------------------------
        group.MapPost("/", async (
            [FromBody] CreateUserCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .RequirePermission("User:Create")
        .WithDescription("创建用户")
        .WithMetadata(new EndpointNameMetadata(nameof(CreateUserCommand)));

        // -----------------------
        // 修改用户
        //------------------------
        group.MapPut("/{id}", async (
            Guid id,
            [FromBody] UpdateUserCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .RequirePermission("User:Update")
        .WithDescription("修改用户")
        .WithMetadata(new EndpointNameMetadata(nameof(UpdateUserCommand)));

        // -----------------------
        // 删除用户
        //------------------------
        group.MapDelete("/", async (
            [FromBody] BatchDeleteUserCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .RequirePermission("User:Delete")
        .WithDescription("删除用户")
        .WithMetadata(new EndpointNameMetadata(nameof(BatchDeleteUserCommand)));

        // -----------------------
        // 重置密码
        //------------------------
        group.MapPost("/{id:guid}/reset-password", async (
            Guid id,
            [FromBody] ResetPasswordCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .RequirePermission("User:Reset:Password")
        .WithDescription("重置密码")
        .WithMetadata(new EndpointNameMetadata(nameof(ResetPasswordCommand)));

        // -----------------------
        // 分页查询
        //------------------------
        group.MapGet("/page", async (
            [AsParameters] UsersWithPaginationQuery request,
            [FromServices] IMediator mediator) =>
        {
            var data = await mediator.Send(request);
            return await Result<PaginatedData<UserDto>>.SucceedAsync(data);
        })
        .RequirePermission("User:View:Page")
        .WithDescription("分页查询")
        .WithMetadata(new EndpointNameMetadata("QueryUsers"));

        // -----------------------
        // 当前用户详情（profile）
        //------------------------
        group.MapGet("/profile", async (
            [FromServices] IMediator mediator) =>
        {
            var data = await mediator.Send(new GetUserByIdQuery());
            return await Result<UserDetail>.SucceedAsync(data);
        })
        .WithDescription("个人信息")
        .WithMetadata(new EndpointNameMetadata(nameof(GetUserByIdQuery)));

        // -----------------------
        // 当前用户的基础信息 mine
        //------------------------
        group.MapGet("/mine", async (
            [FromServices] ICurrentUserService currentUserService,
            [FromServices] IMediator mediator) =>
        {
            var data = await mediator.Send(new GetUserByIdQuery()
            {
                UserId = currentUserService.GetUserId()
            });
            return await Result<UserDetail>.SucceedAsync(data);
        })
        .WithDescription("我的信息")
        .WithMetadata(new EndpointNameMetadata("GetMine"));

        // -----------------------
        // 修改我的信息
        //------------------------
        group.MapPut("/mine", async (
            [FromBody] UpdateMineCommand command,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(command);
        })
        .WithDescription("修改我的信息")
        .WithMetadata(new EndpointNameMetadata(nameof(UpdateMineCommand)));

        // -----------------------
        // 启用/禁用用户
        //------------------------
        group.MapPost("/{id:guid}/status", async (
            Guid id,
            [FromBody] SetUserEnabledStatusCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .RequirePermission("User:Update:Status")
        .WithDescription("启用/禁用")
        .WithMetadata(new EndpointNameMetadata(nameof(SetUserEnabledStatusCommand)));

        // -----------------------
        // 查询用户角色
        //------------------------
        group.MapGet("/{id:guid}/role", async (
            Guid id,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(new GetUserRoleByIdQuery()
            {
                UserId = id
            });
        })
        .RequirePermission("User:Role:View")
        .WithDescription("用户角色")
        .WithMetadata(new EndpointNameMetadata("GetUserRoleById"));

        // -----------------------
        // 分配角色
        //------------------------
        group.MapPost("/{id:guid}/role", async (
            Guid id,
            [FromBody] AssignRoleToUserCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .RequirePermission("User:Role:Assign")
        .WithDescription("分配角色")
        .WithMetadata(new EndpointNameMetadata(nameof(AssignRoleToUserCommand)));

        // -----------------------
        // 上传用户头像
        //------------------------
        group.MapPost("/{id:guid}/avatar", async (
            Guid id,
            [FromBody] UploadAvatarCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .RequirePermission("User:Upload:Avatar")
        .WithDescription("上传用户头像")
        .WithMetadata(new EndpointNameMetadata(nameof(UploadAvatarCommand)));

        // -----------------------
        // 查询偏好
        //------------------------
        group.MapGet("/preferences", async (
            [FromServices] ICurrentUserService currentUserService,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(new GetUserProfileByIdQuery()
            {
                UserId = currentUserService.GetUserId()
            });
        })
        .WithDescription("查询用户偏好")
        .WithMetadata(new EndpointNameMetadata("GetUserProfileById"));

        // -----------------------
        // 编辑偏好
        //------------------------
        group.MapPost("/edit/preferences", async (
            [FromBody] EditUserProfileCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .WithDescription("编辑用户偏好")
        .WithMetadata(new EndpointNameMetadata(nameof(EditUserProfileCommand)));

        // -----------------------
        // 删除偏好
        //------------------------
        group.MapDelete("/preferences", async (
            [FromBody] DeleteUserProfileCommand request,
            [FromServices] IMediator mediator) =>
        {
            return await mediator.Send(request);
        })
        .WithDescription("删除用户偏好")
        .WithMetadata(new EndpointNameMetadata(nameof(DeleteUserProfileCommand)));

        return app;
    }
}
